package com.winit.schedule.task.tracker.quartz;

import org.quartz.JobExecutionContext;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.Trigger.CompletedExecutionInstruction;
import org.quartz.TriggerKey;
import org.quartz.listeners.TriggerListenerSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.winit.schedule.core.repository.constants.QuartzManagerType;
import com.winit.schedule.core.utils.Clock;
import com.winit.schedule.task.tracker.TaskTracker;
import com.winit.schedule.task.tracker.conf.TaskConfiguration;
import com.winit.schedule.task.tracker.quartz.event.QuartzManagerEvent;

public class QuartzTriggerListener extends TriggerListenerSupport {

    private static Logger logger = LoggerFactory.getLogger(QuartzTriggerListener.class);

    private TaskTracker   taskTracker;

    public QuartzTriggerListener(TaskTracker taskTracker){
        this.taskTracker = taskTracker;
    }

    @Override
    public String getName() {
        return "QuartzTriggerListener";
    }

    private TriggerStatisticsInfo getStatisticsInfo(TriggerKey triggerKey, JobExecutionContext context) {
        try {
            TriggerStatisticsInfo statisticsInfo = new TriggerStatisticsInfo(context.getScheduler()
                .getSchedulerInstanceId(), triggerKey.getName(), triggerKey.getGroup());
            return statisticsInfo;
        } catch (SchedulerException e) {
            logger.error("getSchedulerInstanceId failed", e);
            return null;
        }
    }

    @Override
    public void triggerFired(Trigger trigger, JobExecutionContext context) {
        super.triggerFired(trigger, context);
        getStatisticsInfo(trigger.getKey(), context).setLastTriggerTime(Clock.getSystemTime());
    }

    @Override
    public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
        return super.vetoJobExecution(trigger, context);
    }

    @Override
    public void triggerMisfired(Trigger trigger) {
        super.triggerMisfired(trigger);
    }

    @SuppressWarnings("unchecked")
    @Override
    public void triggerComplete(Trigger trigger, JobExecutionContext context,
                                CompletedExecutionInstruction triggerInstructionCode) {
        if (isTaskTrackerStarted()) {
            TriggerStatisticsInfo statisticsInfo = getStatisticsInfo(trigger.getKey(), context);
            if (null != statisticsInfo) {
                statisticsInfo.addJobRuntime(context.getJobRunTime());
                statisticsInfo.setLastTriggerTime(Clock.getSystemTime());
                taskTracker.getDispatcher()
                    .getEventHandler()
                    .handle(new QuartzManagerEvent(QuartzManagerType.UPDATE_STAT, statisticsInfo));
            }
        }
    }

    private boolean isTaskTrackerStarted() {
        return taskTracker.getConfig().getBoolean(TaskConfiguration.USCHEDULE_ENABLE,
            TaskConfiguration.DEFAULT_USCHEDULE_ENABLE);
    }

}
